package com.qmx.smedicinebox.sys.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qmx.smedicinebox.dto.UserLoginDto;
import com.qmx.smedicinebox.dto.UserRegisterDto;
import com.qmx.smedicinebox.dto.UserVerificationDto;
import com.qmx.smedicinebox.sys.dao.UserDao;
import com.qmx.smedicinebox.sys.entity.EmergencyContactEntity;
import com.qmx.smedicinebox.sys.entity.UserEntity;
import com.qmx.smedicinebox.sys.service.EmergencyContactService;
import com.qmx.smedicinebox.sys.service.UserDailyDosageService;
import com.qmx.smedicinebox.sys.service.UserService;
import com.qmx.smedicinebox.utils.*;
import jakarta.annotation.Resource;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.util.*;


@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {
    @Autowired
    private JavaMailSender javaMailSender;
    @Resource
    private TemplateEngine templateEngine;

    @Autowired
    private UserDailyDosageService userDailyDosageService;

    @Autowired
    private EmergencyContactService emergencyContactService;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<UserEntity> page = this.page(
                new Query<UserEntity>().getPage(params),
                new QueryWrapper<UserEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public R logIn(UserLoginDto user) {
        //根据用户名和密码查询
        QueryWrapper<UserEntity> wrapper = Wrappers.query();
        String uUsername = user.getUUsername();
        wrapper.eq("u_username", uUsername);
        UserEntity userEntity = this.baseMapper.selectOne(wrapper);

        if(Objects.isNull(userEntity)){
            return R.error("未查询到相应用户");
        }

        if(userEntity.getUIsValid().equals(UserEntity.INVALID)){
            return R.error("该账户未激活");
        }

        if(!userEntity.getUPassword().equals(user.getUPassword())){
            return R.error("密码错误");
        }


        return R.ok().put("userId",userEntity.getUId())
                .put("msg","登陆成功")
                .put("name",userEntity.getUName())
                .put("email",userEntity.getUEmail())
                .put("phone",userEntity.getUPhone())
                .put("avatar",userEntity.getUAvatar())
                .put("ecId",userEntity.getUEmergencyContact());

    }

    @Override
    public R register(UserRegisterDto user) {
//        检验该账户是否注册
        LambdaQueryWrapper<UserEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(UserEntity::getUEmail, user.getUEmail());
        UserEntity registerUser = this.baseMapper.selectOne(lambdaQueryWrapper);

        if(Objects.nonNull(registerUser)&&registerUser.getUIsValid().equals(UserEntity.VALID)){
//账户不为空且已激活,说明账户已被注册过
            return R.error("此账户已被注册");
        }else{
//            账户为空或者未激活,都可以将原来的账户内容删除,进行新的创建
            this.baseMapper.delete(lambdaQueryWrapper);
        }

//        验证邮箱格式
        Boolean qqEmail = EmailUtil.isQQEmail(user.getUEmail());
        Boolean neteaseEmail = EmailUtil.isNeteaseEmail(user.getUEmail());
        if(!qqEmail&&!neteaseEmail){
            return R.error("账号格式有误");
        }


//        为用户创建账号
        UserEntity users = new UserEntity();
        users.setUUsername(user.getUUsername());
        users.setUEmail(user.getUEmail());
        users.setUName(user.getUName());
        users.setUPassword(user.getUPassword());
        Boolean account = createAccount(users);

        if(!account){
            return R.error("创建账号出错");
        }

//        向用户发送验证码
        Boolean aBoolean = sendRegisterEmail(user.getUEmail(),users.getUVerifyCode());
        if(!aBoolean){
            return R.error("发送邮件失败");
        }else{
            return R.ok("发送邮件成功，请及时查收");
        }
    }

    @Override
    public R verification(UserVerificationDto user) {
        System.out.println(user);
        Date date = new Date();
        //查询该账号
        LambdaQueryWrapper<UserEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(UserEntity::getUEmail, user.getUEmail());
        UserEntity registerUser = this.baseMapper.selectOne(lambdaQueryWrapper);
        if (Objects.isNull(registerUser)) {
            return R.error("未找到该注册账号");
        }

        if (registerUser.getUIsValid().equals(UserEntity.INVALID)) {
//            当账户存在但未激活时，进行后续的逻辑
            if (Objects.isNull(user.getUVerifyCode())) {
//                如果验证码为空，传入参数有误，不能激活账号
                return R.error("该账户未激活或验证码有误");

            } else if (user.getUVerifyCode().equals(registerUser.getUVerifyCode())
                    && DateTimeUtil.PreviousToNow(registerUser.getUVerifyCodeTime(), date)<UserEntity.VERIFYCODE_TIME_LIMIT) {
//                验证码正确且验证码未超时，激活账号并更新账号
                registerUser.setUIsValid(UserEntity.VALID);

                System.out.println(registerUser);


                userDailyDosageService.saveDefault(registerUser.getUId());

                EmergencyContactEntity emergencyContactEntity = emergencyContactService.saveDefault(registerUser.getUId());
                System.out.println("emergencyContactEntity");
                System.out.println(emergencyContactEntity);
                registerUser.setUEmergencyContact(emergencyContactEntity.getEcId());
                this.baseMapper.updateById(registerUser);

                return R.ok("账户激活成功");

            } else if(user.getUVerifyCode().equals(registerUser.getUVerifyCode())
                    && DateTimeUtil.PreviousToNow(registerUser.getUVerifyCodeTime(),date)>UserEntity.VERIFYCODE_TIME_LIMIT){
//                验证码正确，但是超时了，返回该逻辑
                return R.error("验证码时间已过期,请重新发送邮件");

            }else {
//验证码出错
                return R.error("验证码错误");
            }
        }else if(registerUser.getUIsValid().equals(UserEntity.VALID)){
//            如果账户的isValid为真，则说明这个账户已经存在并且激活
            return R.error("已存在该用户");
        }else{
//            如果账户的isValid为null，则说明数据有问题
            return R.error("IsValid is mast "+UserEntity.VALID+" or "+UserEntity.INVALID);
        }
    }

    //    注册账号时创建账号
    public Boolean createAccount(UserEntity user){
//        赋值为未激活
        user.setUIsValid(UserEntity.INVALID);


//生成验证码
        String s = IdUtil.getSnowflake(1, 1).nextIdStr();
        user.setUVerifyCode(s.substring(s.length() - 4));


////        加密密码
//        if(!"".equals(user.getUPassword())&&!Objects.isNull(user.getUPassword())){
//            String s2 = passwordEncoder.encode(user.getPassword());
//            user.setPassword(s2);
//        }

//生成或更新验证密码
        System.out.println(new Date());
        user.setUVerifyCodeTime(new Date());

        int insert = this.baseMapper.baseInsert(user);
        return insert==0?false:true;
    }

    //    发送邮件
    public Boolean sendRegisterEmail(String email,String verifyCode) {
        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, false);
            mimeMessageHelper.setFrom(EmailUtil.mailObject);
            mimeMessageHelper.setTo(email);
            mimeMessageHelper.setSubject("药箱系统欢迎你");
            Context context = new Context();
            System.out.println(verifyCode);
            context.setVariable("verifyCode",verifyCode);
            String text = templateEngine.process("active-account.html", context);
            mimeMessageHelper.setText(text,true);
            javaMailSender.send(mimeMessage);
            return true;
        } catch (MessagingException e) {
            return false;
        }
    }
}